use std::collections::{BTreeMap, HashMap};

use axum::http::HeaderMap;
use criterion::async_executor::FuturesExecutor;
use criterion::black_box;
use criterion::{criterion_group, Criterion};
use nacos_demo::*;
use std::time::Instant;
use tracing::log::info;
use urlencoding::encode;

pub async fn test_normal_handler() {
    log_init();
    info!("获取配置开始");
    let get_configs = Request {
        data: Configs::default(),
        url: RequestUrl::GetConfigs,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let get_config_res = normal_handler(&get_configs).await;

    info!("获取配置结束 {get_config_res:?}");
    info!("监听配置开始");
    let config = Configs::default();
    let mut headers = HeaderMap::new();
    headers.insert("Long-Pulling-Timeout", 3.into());
    let post_configs = Request {
        data: ListeningConfigs::new(&config, "f53d8f020f43e8265612bcb12ec88c1e"),
        url: RequestUrl::PostConfigLinsten,
        headers: Some(headers),
        content_type: RequestContentType::Form,
    };
    let post_configs_res = normal_handler(&post_configs).await.unwrap();
    tracing::info!("监听配置结束 {post_configs_res:#?}");

    info!("发布配置开始");
    let mut map = BTreeMap::new();
    map.insert("x1".to_string(), 1.0);
    map.insert("y1".to_string(), 2333.0);

    // Serialize it to a YAML string.
    let yaml = serde_yaml::to_string(&map).unwrap();
    let publish_config = Request {
        data: ConfigsPublish {
            content: yaml.replace("\\", ""),
            content_type: "yaml".to_string(),
            configs: Configs::default(),
        },
        url: RequestUrl::PostConfigs,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let publish_config_res = normal_handler(&publish_config).await;
    info!("发布配置结束 {publish_config_res:?}");

    info!("删除配置开始");
    let del_configs = Request {
        data: Configs::default(),
        url: RequestUrl::DeleteConfigs,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let del_config_res = normal_handler(&del_configs).await;
    info!("删除配置结束 {del_config_res:?}");
    info!("查询配置历史版本开始");
    let req = Request {
        data: HistoryConfigs::default(),
        url: RequestUrl::GetHistoryConfigs,
        headers: Default::default(),
        content_type: Default::default(),
    };

    let res = normal_handler(&req).await.unwrap();
    let res_1: HistoryConfigsRes = serde_json::from_str(&res.data.unwrap()).unwrap();
    tracing::info!("查询配置历史版本结束 {res_1:#?}");

    info!("查询配置历史版本详情开始");
    let req = Request {
        data: HistoryConfigInfo::new(214.to_string().to_string(), Configs::default()),
        url: RequestUrl::GetHistoryConfigsInfo,
        headers: Default::default(),
        content_type: Default::default(),
    };

    let res = normal_handler(&req).await.unwrap();
    let res_1: HistoryConfigInfoRes = serde_json::from_str(&res.data.unwrap()).unwrap();
    tracing::info!("查询配置历史版本详情结束 {res_1:#?}");

    info!("查询配置上一版本信息(1.4起)开始");
    let req = Request {
        data: PreviousHistoryConfigInfo::new(res_1.id, Configs::default()),
        url: RequestUrl::GetHistoryPreviousConfigsInfo,
        headers: Default::default(),
        content_type: Default::default(),
    };

    let res = normal_handler(&req).await;
    info!("查询配置上一版本信息(1.4起)结束{res:?}");

    info!("注册实例开始");
    let req = Request {
        data: Instance::default(),
        url: RequestUrl::PostServiceInstance,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await;
    info!("注册实例结束{res:?}");
    info!("注销实例开始");
    let req = Request {
        data: Instance::default(),
        url: RequestUrl::DeleteServiceInstance,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await;
    info!("注销实例结束{res:?}");

    info!("修改例开始");
    let req = Request {
        data: Instance::default(),
        url: RequestUrl::PutServiceInstance,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await;
    info!("修改实例结束{res:?}");

    info!("查询实例列表开始");
    let req = Request {
        data: InstanceQueryList::default(),
        url: RequestUrl::GetServiceInstanceList,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await;
    info!("查询实例列表结束{res:?}");

    info!("查询实例详情开始");
    let req = Request {
        data: Instance::default(),
        url: RequestUrl::GetServiceInstance,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await;
    info!("查询实例详情结束{res:?}");

    info!("发送实例心跳开始");
    let mut map = HashMap::new();
    map.insert(
        "preserved.register.source".to_string(),
        "SPRING_CLOUD".to_string(),
    );
    let beat = Beat {
        cluster: Default::default(),
        ip: "10.0.16.24".to_string(),
        metadata: Some(map),
        port: 8082,
        scheduled: true,
        service_name: "service-job-gateway".to_string(),
        weight: 1,
    };
    let beat_json = serde_json::to_string(&beat).unwrap();
    let json = encode(&beat_json).into_owned();
    let req = Request {
        data: InstanceBeat {
            service_name: Some("service-job-gateway".to_string()),
            ip: Some("10.0.16.24".to_string()),
            port: Some("8082".to_string()),
            namespace_id: Default::default(),
            group_name: Default::default(),
            ephemeral: Default::default(),
            beat: Some(json),
        },
        url: RequestUrl::PutServiceInstanceBeat,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await;
    info!("发送实例心跳结束{res:?}");

    info!("创建服务开始");
    let req = Request {
        data: Service::default(),
        url: RequestUrl::PostService,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await;
    info!("创建服务结束{res:?}");
    info!("修改服务开始");
    let req = Request {
        data: Service::default(),
        url: RequestUrl::PutService,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await;
    info!("修改服务结束{res:?}");

    info!("查询服务开始");
    let req = Request {
        data: Service::default(),
        url: RequestUrl::GetService,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await.unwrap();

    let res_1: ServiceInfoRes = serde_json::from_str(&res.data.unwrap()).unwrap();
    info!("查询服务结束{res_1:?}");

    info!("删除服务开始");
    let req = Request {
        data: Service::default(),
        url: RequestUrl::DeleteService,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await;
    info!("删除服务结束{res:?}");

    info!("查询服务列表开始");
    let req = Request {
        data: ServiceListQuery::default(),
        url: RequestUrl::GetServiceList,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await;
    info!("查询服务列表开始{res:?}");

    info!("查询系统开关");
    let req = Request {
        data: OperatorSwitches {
            entry: Some(String::default()),
            value: Some(String::default()),
            debug: Some(String::default()),
        },
        url: RequestUrl::GetSysOperterSwitch,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await.unwrap();

    let res_1: OperatorSwitchesRes = serde_json::from_str(&res.data.unwrap()).unwrap();
    info!("查询系统开关{res_1:?}");

    info!("修改系统开关");
    let req = Request {
        data: OperatorSwitches {
            entry: Some("pushEnabled".to_string()),
            value: Some("true".to_string()),
            debug: Some("false".to_string()),
        },
        url: RequestUrl::PutSysOperterSwitch,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await.unwrap();

    info!("修改系统开关{res:?}");

    info!("查看系统当前数据指标");
    let req = Request {
        data: OperatorMetrics {},
        url: RequestUrl::GetSysOperterMetrics,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await.unwrap();

    let res_1: OperatorMetricsRes = serde_json::from_str(&res.data.unwrap()).unwrap();
    info!("查看系统当前数据指标{res_1:?}");

    info!("查看当前集群Server列表");
    let req = Request {
        data: OperatorServers {
            healthy: Some("true".to_string()),
        },
        url: RequestUrl::GetSysOperterMetrics,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await.unwrap();

    let res_1: OperatorServersRes = serde_json::from_str(&res.data.unwrap()).unwrap();
    info!("查看当前集群Server列表{res_1:?}");

    info!("查看当前集群leader");
    let req = Request {
        data: RaftLeader {},
        url: RequestUrl::GetSysRaftLeader,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await;

    // let res_1: RaftLeaderRes = serde_json::from_str(&res.data.unwrap()).unwrap();
    info!("查看当前集群leader{res:?}");

    info!("更新实例的健康状态");
    let req = Request {
        data: InstanceHealthy::default(),
        url: RequestUrl::PutHealthInstance,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await;

    info!("更新实例的健康状态{res:?}");

    info!("批量更新实例元数据(Beta)");
    info!("批量删除实例元数据(Beta)");
    info!("查询命名空间列表开始");
    let req = Request {
        data: ConsoleNamespaces::default(),
        url: RequestUrl::GetConsoleNameSpaces,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await;
    info!("查询命名空间列表结束{:?}", &res);
    let json = res.unwrap().data.unwrap();
    let res_1: ConsoleNamespacesRes = serde_json::from_str(json.as_str()).unwrap();
    info!("查询命名空间列表结束{res_1:?}");

    info!("创建命名空间");
    let req = Request {
        data: ConsoleNamespaces {
            custom_namespace_id: Some("123455".to_string()),
            namespace_name: Some("123455".to_string()),
            namespace_desc: Some("123455".to_string()),
            namespace_id: Some("".to_string()),
            namespace_show_name: Some("".to_string()),
            namespace: Some("".to_string()),
        },
        url: RequestUrl::PostConsoleNameSpaces,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await;
    info!("创建命名空间结束{:?}", &res);

    info!("修改命名空间");
    let req = Request {
        data: ConsoleNamespaces {
            custom_namespace_id: Some("".to_string()),
            namespace_name: Some("".to_string()),
            namespace_desc: Some("ssssssssaaaa".to_string()),
            namespace_id: Some("".to_string()),
            namespace_show_name: Some("ssssssssss".to_string()),
            namespace: Some("123455".to_string()),
        },
        url: RequestUrl::PutConsoleNameSpaces,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await;
    info!("修改命名空间{:?}", &res);

    info!("删除命名空间");
    let req = Request {
        data: ConsoleNamespaces {
            custom_namespace_id: Some("".to_string()),
            namespace_name: Some("".to_string()),
            namespace_desc: Some("".to_string()),
            namespace_id: Some("123455".to_string()),
            namespace_show_name: Some("".to_string()),
            namespace: Some("".to_string()),
        },
        url: RequestUrl::DeleteConsoleNameSpaces,
        headers: Default::default(),
        content_type: Default::default(),
    };
    let res = normal_handler(&req).await;
    info!("删除命名空间{:?}", &res);
}
fn compare_api(c: &mut Criterion) {
    let mut group = c.benchmark_group("nacos-api");

    group.bench_function("iter", move |b| {
        b.to_async(FuturesExecutor).iter_custom(|iters| async move {
            let start = Instant::now();
            for _i in 0..iters {
                black_box(test_normal_handler().await);
            }
            start.elapsed()
        })
    });
}

criterion_group!(test_normal, compare_api);
